package com.ly.demo.classdemo;

/**
 * @author liuyang
 * @des 类装载器是用来把类(class)装载进JVM的。JVM规范定义了两种类型的类装载器：启动内装载器(bootstap)和用户自定义装载器(user-defined class loader).
 * Bootstap（启动类加载器）是JVM自带的类装载器，负责装载Java平台核心类库，如java.lang.*等，在Java中看不到他，是null
 * Extension(扩展类加载器) 主要负责jdk_home/lib/ext目录下的jar包或—Djava.ext.dirs指定目录下的jar包装入工作
 * System(系统类加载器) 主要负责java-classpath/-Djava.class.path所指定的目录下的类与jar包装入工作
 * <p>
 * java提供了抽象类ClassLoader，所有用户自定义类装载器都实例化自ClassLoader的子类。ClassLoader是一个特殊的用户自定义类装载器，有JVM的实现者提供，如不特殊指定，其将作为系统缺省的装载器。
 * @Version 1.0
 * @Date: 05/08/2021 09:52
 */
public class ClassLoaderDemo {
    public static void main(String[] args) {
        ClassLoader classloader;
        classloader = ClassLoader.getSystemClassLoader();
        System.out.println(classloader);
        //sun.misc.Launcher$AppClassLoader@18b4aac2

        //加载过程
        //
        //　　ClassLoader加载类时，首先检查缓存中是否有该类
        //　　(1)  若有直接返回
        //　　(2)  若无，请求父类加载
        //　　(3)  如果父类无法加载，则从bootstap classLoader加载
        //
        //　　然后加载指定类，搜索的顺序是：
        //　　(1)  寻找class文件（从与此classloader相关的类路径中寻找）
        //　　(2)  从文件载入class
        //　　(3)  找不到则抛出ClassNotFoundException
        while (classloader != null) {
            classloader = classloader.getParent();
            System.out.println(classloader);
            // 1.sun.misc.Launcher$ExtClassLoader@5d099f62
            // 2.null
        }//此过程在自底向上判断类加载器

        try {
            Class c1 = Class.forName("java.lang.Object");//返回Object的对象
            classloader = c1.getClassLoader();//获得该对象的类加载器
            System.out.println("java.lang.Object`s loader is " + classloader);
            c1 = Class.forName("com.ly.demo.classdemo.ClassLoaderDemo");
            classloader = c1.getClassLoader();
            System.out.println("ClassLoaderDemo`s loader is " + classloader);
        } catch (Exception e) {
            System.out.println("Check name of the class");
        }
        //sun.misc.Launcher$AppClassLoader@1016632　　//表示系统类加载器实例化自sun.misc.Launcher$AppClassLoader
        //sun.misc.Launcher$ExtClassLoader@dc6a77　　 //表示系统类装载器的parent实例化自类sun.misc.Launcher$ExtClassLoader
        //null　　　　　　　　　　　　　　　　　　　　　　　//表示系统类加载器的parent的parent为bootstap，无法直接获取
        //java.lang.Object`s loader is null　　　　　　//表示类Object是由bootstap装载的
        //ClassLoaderDemo`s loader is sun.misc.Launcher$AppClassLoader@1016632　　//表示用户自己写的类是由系统类装载器装载的
    }
}
